#encoding=utf8
import pprint
import ply.yacc as yacc
from copy import copy
from mylex import tokens
from  mylex import findCString
from color import Color

db={}

def p_sql(p):
    '''sql : sql_create
           | sql_drop
           | sql_show
           | sql_insert
           | sql_select
    '''
    p[0]=p[1]

def p_sql_select(p):
    ''' sql_select : SELECT sql_expr from_expr where_expr order_expr
    '''
    p[0] = {
        'type':'SELECT',
        'row': p[2],
        'from':p[3],
        'where_expr':p[4],
        'order_expr':p[5]
    }

def p_sql_expr(p):
    ''' sql_expr : O_MUL
    '''
    if len(p) == 2:
        p[0] = p[1]
    else :
        pass
        #todo 
        #
def p_from_expr(p):
    ''' from_expr : FROM ID
                  | 
    '''
    if len(p)==3 :
        p[0]=p[2]

def p_where_expr(p):
    ''' where_expr : 
    '''

def p_order_expr(p):
    ''' order_expr :
    '''

def p_sql_insert(p):
    ''' sql_insert : INSERT INTO ID VALUES O_LEFT sql_insert_list O_RIGHT
    '''
    p[0] = {
        'type':'INSERT',
        'table':p[3],
        'values':p[6]
    }

def p_sql_insert_list(p):
    ''' sql_insert_list : sql_insert_list O_COMMA sql_insert_value
                        | sql_insert_value
    '''
    if len(p) ==2 : 
        p[0]=[p[1]]
        return
    p[0] = p[1]
    p[0].append(p[3])

def p_sql_insert_value(p):
    ''' sql_insert_value : NUMBER
                         | STRING
                         | FLOAT
    '''
    p[0] = p[1]
def p_sql_show(p):
    '''sql_show : SHOW TABLES
    '''
    p[0]={
        'type':'SHOW TABLES',
    }

def p_sql_drop(p):
    ''' sql_drop : DROP TABLE ID 
    '''
    p[0] = {
        'type':'DROP',
        'table':p[3]
    }

def p_sql_create(p):
    '''sql_create : CREATE TABLE ID O_LEFT create_row_list O_RIGHT'''
    p[0] = {
        'type':'CREATE',
        'table name':p[3],
        'row' : p[5]
    }

def p_sql_create_row_list(p):
    '''create_row_list : create_row_list O_COMMA create_row
                       | create_row
    '''
    if len(p) == 2 :
        p[0]=[p[1]]
    else :
        p[1].append(p[3])
        p[0]=p[1]

def p_create_row(p):
    '''create_row : ID INTERGER
                  | ID INT
                  | ID REAL
                  | ID VARCHAR
                  | PRIMARY KEY O_LEFT ID O_RIGHT
    '''
    if len(p) ==3:
        p[0]=[p[1],p[2]]
    else :
        p[0] = {'PRIMARY KEY':p[4]}

def p_error(p):
    print "###error: ",p



precedence = (
    # ('left', 'MAIOR'),
    # ('left','PARENTESES_ESQUERDO'),
    # ('left','IN'),
)


parser = yacc.yacc()


def execute(T,textList):
    what = T['type']
    if what == 'CREATE':
        db[T['table name']]={
            'data':[],
            'row':T['row']
        }
    elif what == 'DROP':
        del db[T['table']]
    elif what == 'SHOW TABLES':
        return db.keys()
    elif what == "INSERT":
        # assert(len(T["values"]) == len(db[T['table']]['row']) )
        t=[]
        for i in T['values']: 
            if type(i) == type(''):
                t.append(textList[int(i)])
            else : t.append(i)
        # todo 类型转换
        db[T['table']]['data'].append(t)
    elif what == 'SELECT':
        ans = db[T['from']]['data']
        if T['row'] =='*':
            return ans


def test(s,out=False):
    # def myprint(s,tab=0):
        # if not tab: print s
        # for i in s:
        #     if type(i) == list: print '\t'*(1+tab)+'|' ,i
        #     # else : print '|'+str(i)
        #     if type(i) == list: myprint (i,tab+1)
    if out:print "INPUT: ",s
    s,textList = findCString(s)
    if out: print s,textList
    result = parser.parse(s)
    if out: pprint.pprint(result)
    exe_out = execute(result,textList)
    if out: print exe_out
    return exe_out

def testAll():
    s="""CREATE TABLE db_test ( first_col INTERGER,second_col VARCHAR,
         PRIMARY KEY(first_col) )
    """
    test(s)
    s= "SHOW TABLES"
    # test(s)

    s="DROP TABLE db_test"
    # test(s)

    s='INSERT INTO db_test VALUES(434.35,"fsf")'
    test(s)

    s='INSERT INTO db_test VALUES("dsd","dsd")'
    test(s)

    s='INSERT INTO db_test VALUES(54,"sfd")'
    test(s)

    s='SELECT * FROM db_test'
    print test(s)

    s='INSERT INTO db_test VALUES("AAAA","BBBB")'
    test(s)
    # print '#'*100
    # pprint.pprint(db)

testAll()

if __name__ =='__main__':
    co=Color()
    while 1:
        try:
            line = raw_input("SQL:")
        except EOFError:
            raise SystemExit
        if not line: continue
        # print line
        try:
            # pprint.pprint(test(line))
            co.print_red_text(test(line))  
        except Exception,e:
            print e
